﻿using System;
using System.Web.Mvc;
using Dgg.Anug.Cqrs.Core.Application.DefectHandling.Commands;
using Dgg.Anug.Cqrs.Core.Application.DefectHandling.Queries;
using Dgg.Anug.Cqrs.Core.Infrastructure.Commanding;
using Dgg.Anug.Cqrs.Core.Presentation.Models.DefectHandling;
using MvcContrib;
using MvcContrib.EnumerableExtensions;

namespace Dgg.Anug.Cqrs.Core.Presentation.Controllers
{
	public class IssueController : BaseController
	{
		private readonly IQueryRepository _queries;
		private readonly CommandExecutor<OpenIssue> _openExecutor;
		private readonly CommandExecutor<FixIssue> _fixExecutor;
		private readonly CommandExecutor<CloseIssue> _closeExecutor;
		private readonly CommandExecutor<DeleteIssue> _deleteExecutor;

		public IssueController(IQueryRepository queries,
			CommandExecutor<OpenIssue> openExecutor,
			CommandExecutor<FixIssue> fixExecutor,
			CommandExecutor<CloseIssue> closeExecutor,
			CommandExecutor<DeleteIssue> deleteExecutor)
		{
			_queries = queries;
			_openExecutor = openExecutor;
			_fixExecutor = fixExecutor;
			_closeExecutor = closeExecutor;
			_deleteExecutor = deleteExecutor;
		}

		public ActionResult Index()
		{
			return this.RedirectToAction(c => c.List());
		}

		public ActionResult List()
		{
			return View(_queries.ListIssues());
		}

		public ActionResult Open()
		{
			//TODO: find a better way for populating the dropdowlists
			setSupportEntitiesForOpening();

			OpenIssue empty = new OpenIssue();
			return View(empty);
		}

		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Open(OpenIssue command)
		{
			return Validating(command, () =>
			{
				_openExecutor.Execute(command);
				return this.RedirectToAction(c => c.List());
			},
			invalidModel => setSupportEntitiesForOpening());
		}

		public ActionResult Fix(Guid id)
		{
			//TODO: find a better way for populating the dropdowlists
			setSupportEntitiesForFixing();
			Issue issue = _queries.GetIssue(id);

			var empty = new FixIssue(id) { Title = issue.Title };
			return View(empty);
		}

		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Fix(FixIssue command)
		{
			return Validating(command, () =>
			{
				_fixExecutor.Execute(command);
				return this.RedirectToAction(c => c.List());
			},
			invalidModel => setSupportEntitiesForFixing());
		}

		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Close(Guid id)
		{
			var command = new CloseIssue(id);
			return Validating(command, () =>
			{
				_closeExecutor.Execute(command);
				return this.RedirectToAction(c => c.List());
			});
		}

		[AcceptVerbs(HttpVerbs.Delete)]
		public ActionResult Delete(Guid id)
		{
			var command = new DeleteIssue(id);
			return Validating(command, () =>
			{
				_deleteExecutor.Execute(command);
				return this.RedirectToAction(c => c.List());
			});
		}

		private void setSupportEntitiesForOpening()
		{
			SupportEntities entities = _queries.GetSupportEntities();

			ViewData[OpenIssue.Solutions] = entities.Solutions.ToSelectList(s => s.Id, s => s.Name);
			ViewData[OpenIssue.Versions] = entities.Versions.ToSelectList(s => s.Id, s => s.Name);
			ViewData[OpenIssue.Builds] = entities.Builds.ToSelectList(s => s.Id, s => s.Name);
		}

		private void setSupportEntitiesForFixing()
		{
			SupportEntities entities = _queries.GetSupportEntities();

			ViewData[OpenIssue.Versions] = entities.Versions.ToSelectList(s => s.Id, s => s.Name);
			ViewData[OpenIssue.Builds] = entities.Builds.ToSelectList(s => s.Id, s => s.Name);
		}
	}
}
